#ifndef STRING_HPP
#define STRING_HPP

/********************************************************************
	created:	2011/01/14
	filename: 	E:\C++\Red\src\Utils\String.hpp
	author:		Red
	
	purpose:	String Wrapper class. Permit concatenation and stuff.
*********************************************************************/

#include <sstream>
#include <vector>
#include <algorithm>
#include <cctype>
#include "Math/Vector2.hpp"
#include "Math/Vector3.hpp"

namespace red {
	class Color;

	/// Ease of use class for string managment, allowing String creation from multiple types
	class String{
	public:
		/// Default Ctor
		String(){ mString << "";}
		
		/// Copy Ctor
		String(const String &s){ mString << s.str(); }

		/// Ctor from any data type
		template<typename T> String(const T& ppValue);

		/// Operators allowing concatenation of different data types
		template<typename T> String& operator+(const T &ppValue);
		template<typename T> String& operator+=(const T &ppValue);

		/// Stream operator (maybe useless with above one)
		friend std::ostream& operator<<(std::ostream& oss, const String &pStr);

		/// Cast operator in std::string
		operator std::string() const;
		
		/// Explicit Cast operator in std::string
		std::string str() const;

		/// Comparison operators
		bool operator==(const std::string &pStr) const;
		bool operator !=(const std::string &pStr) const;

		/// Affectation operators
		void operator=(const std::string &pStr);
		void operator=(const String &pStr);

		/// Returns the oss for string operations
		std::ostringstream& ostr();

		/// Returns the String length
		size_t size() const;

		/// Returns true if the String is empty
		bool Empty() const;

		/// Returns true if the String is a commentary (begins with "//")
		bool IsCommentary() const;

	protected:
		std::ostringstream mString;
	};

	/// Vector of strings
	typedef std::vector<std::string> StringVector;

	
	
	/// String utility functions
	class StringUtils{
	public:
		/// Splits a string according to different separators
		/// @param pIn       : input string to be splitted
		/// @param pSep      : different char separators
		/// @param pMaxSplit : max splits operation. 0 means infinite
		static StringVector SplitString(const std::string &pIn, const std::string &pSep = "\t\n ", u32 pMaxSplit = 0);

		/// Returns the lower case input string
		static std::string ToLower(const std::string &pStr);

		/// Returns the upper case input string
		static std::string ToUpper(const std::string &pStr);

		/// Returns only the extension of a complete file name
		static std::string GetExtension(const std::string &pFileName);

		/// Returns only the file name without its extension
		static std::string GetFileName(const std::string &pFileName);

		/// Check if a string begins by another
		/// @param pStr : string to check
		/// @param pStart : substring used for comparison
		/// @param pLowerCase : true for a case insensitive comparison
		static bool StartsWith(const std::string &pStr, const std::string &pStart, bool pLowerCase = true);
	};


	/// String Converter (types -> String & String -> types)
	class StringConverter{
	public:
		/// STRING TO FLOAT
		static f32 ToFloat(const std::string &pVal);

		/// STRING TO INT
		static s32 ToInt(const std::string &pVal);

		/// STRING TO UNSIGNED
		static u32 ToUnsigned(const std::string &pVal);

		/// STRING TO BOOL
		static bool ToBool(const std::string &pVal);

		/// STRING to VECTOR2
		static Vector2F ToVector2(const std::string &pVal);

		/// STRING to VECTOR3
		static Vector3F ToVector3(const std::string &pVal);

		/// STRING to COLOR
		static Color ToColor(const std::string &pVal);

		/// FLOAT to STRING
		static String ToString(f32 pVal, u16 pPrecision = 6);

		/// DOUBLE to STRING
		static String ToString(f64 pVal, u16 pPrecision = 6);

		/// LINT to STRING
		static String ToString(s32 pVal);

		/// SHORT to STRING
		static String ToString(s16 pVal);

		/// UNSIGNED to STRING
		static String ToString(u16 pVal);
	};

	#include "String.inl"
}
#endif 
